package com.lab.forthreadpool;


import com.lab.util.StringUtil;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;

/**
 * @author weiwei
 */
public class Block {
//    public Block[] preBlock;
    public String hash; //自己的hash
    public String[] previousHash;//前面区块的hash
    public String merkleRoot;//默克尔树
    public List<Transaction> transactions =
            Collections.synchronizedList(new ArrayList<Transaction>()); //our data will be a simple message.线程安全的
    public long timeStamp; //从1970 1/1开始的时间戳（单位毫秒）
    public int nonce;//计算出的nonce

    //Block Constructor.
    public Block(String... previousHash) {
        this.previousHash = previousHash;
        this.timeStamp = new Date().getTime();
//        preBlock = new Block[previousHash.length];

        this.hash = calculateHash(); //Making sure we do this after we set the other values.
    }

    //Calculate new hash based on blocks contents
    public String calculateHash() {
        String calculatedhash = StringUtil.applySha256(
                previousHash +
                        Long.toString(timeStamp) +
                        Integer.toString(nonce) +
                        merkleRoot
        );
        return calculatedhash;
    }

    //Increases nonce value until hash target is reached.
    public void mineBlock(int difficulty) {
        merkleRoot = StringUtil.getMerkleRoot(transactions);
        System.out.println(merkleRoot);
        String target = StringUtil.getDificultyString(difficulty); //创建difficulty个'0'
        System.out.println("开始hash！");
        while (!hash.substring(0, difficulty).equals(target)) {
            nonce++;
            hash = calculateHash();
        }
        System.out.println("Block Mined!!! : " + hash);
    }

    //Add transactions to this block
    public boolean addTransaction(Transaction transaction) {
        //process transaction and check if valid, unless block is genesis block then ignore.
        if (transaction == null)
            return false;
        if ((previousHash[0] != "0")) {
            if ((transaction.processTransaction() != true)) {
                System.out.println("Transaction failed to process. Discarded.");
                return false;
            }
        }

        transactions.add(transaction);
        System.out.println("Transaction Successfully added to Block");
        return true;
    }
}
